/*
 * TunedBoyerMoore.cpp
 *
 *  Created on: 27-08-2013
 *      Author: Krzychu
 */

#include "TunedBoyerMoore.h"

#include "../Structures/Config.h"

#include <stdio.h>
#include <string.h>

#define ASIZE 255

TunedBoyerMoore::TunedBoyerMoore()
{

}

TunedBoyerMoore::~TunedBoyerMoore()
{

}

std::string TunedBoyerMoore::getName()
{
	return "Tuned Boyer-Moore";
}

searchResult TunedBoyerMoore::execute(std::string text, std::string pattern)
{
	searchResult result;
	result.iterationsTaken = 0;

	int j, k, shift;

	int textLength = text.length();
	int patternLength = pattern.length();

	const char* textChar = text.c_str();
	const char* patternChar = pattern.c_str();

	/* Preprocessing */
	int* bmBc = pre_bad_character_shift(pattern);
	shift = bmBc[pattern[patternLength - 1]];
	bmBc[pattern[patternLength - 1]] = 0;
	//memset((char*)textChar + textLength, pattern[patternLength - 1], patternLength);

	/* Searching */
	j = 0;
	while (j < textLength)
	{
		result.iterationsTaken++;
		k = bmBc[textChar[j + patternLength - 1]];
		while (k != 0 && j < textLength)
		{
			j += k;
			k = bmBc[textChar[j + patternLength - 1]];
			j += k;
			k = bmBc[textChar[j + patternLength - 1]];
			j += k;
			k = bmBc[textChar[j + patternLength - 1]];
		}
		if (memcmp(patternChar, textChar + j, patternLength - 1) == 0 && j < textLength)
		{
			result.positionsFound.push_back(j);
			if (Config::getInstance()->getFindOneOccurence())
			{
				return result;
			}
		}
		j += shift; /* shift */
	}

	return result;
}
